﻿using Basic.FlowApplication.Interface;
using Basic.FlowApplication.Model.AuditItem;
using Basic.FlowApplication.Model.AuditLog;
using Basic.FlowCollect;
using Basic.FlowModel.AuditLog;
using Basic.FlowModel.AuditLogItem;
using Basic.FlowModel.AuditState;
using Basic.FlowRemoteModel;
using WeDonekRpc.Client;
using WeDonekRpc.Helper;

namespace Basic.FlowApplication.lmpl
{
    internal class AuditLogService : IAuditLogService
    {
        private readonly IFlowAuditLogCollect _AuditLog;
        private readonly IFlowAuditItemLogCollect _ItemLog;
        private readonly IFlowAuditNodeStateCollect _NodeState;

        public AuditLogService ( IFlowAuditLogCollect auditLog,
            IFlowAuditItemLogCollect itemLog,
            IFlowAuditNodeStateCollect nodeState )
        {
            this._AuditLog = auditLog;
            this._ItemLog = itemLog;
            this._NodeState = nodeState;
        }
        public AuditItemLog GetItem ( long id )
        {
            return this._ItemLog.GetAuditLog(id);
        }
        public long[] GetAuditEmpId ( long logId, long rootBatchNo, long nodeId )
        {
            return this._ItemLog.GetNodeAuditEmpId(logId, rootBatchNo, nodeId);
        }
        public NodeAuditItem[] GetBackNode ( long logId, AuditItemLog log )
        {
            long[] nodeId = this._NodeState.GetGoByNodeId(logId, log.RootNodeId);
            if ( nodeId.IsNull() )
            {
                return null;
            }
            return this._ItemLog.GetGoByNode<NodeAuditItem>(log.RootBatchNo, nodeId);
        }
        public FlowAuditLogState GetLogState ( long logId )
        {
            AuditLogDto log = this._AuditLog.Get<AuditLogDto>(logId);
            if ( log.Status == FlowAuditLogStatus.已结束 )
            {
                throw new ErrorException("flow.audit.already.end");
            }
            AuditItemInfo[] items = this._ItemLog.GetsByLogId<AuditItemInfo>(logId);
            if ( items.IsNull() )
            {
                throw new ErrorException("flow.audit.item.null");
            }
            AuditNodeState[] nodeState = this._NodeState.GetRunNode(logId);
            return new FlowAuditLogState(log, items, nodeState);
        }


        public AuditLog SaveResult ( SaveAuditBody body )
        {
            AuditResult result = this._AuditLog.SaveAuditResult(body);
            AuditLogDto log = this._AuditLog.Get<AuditLogDto>(result.LogId);
            AuditLog dto = log.ConvertMap<AuditLogDto, AuditLog>();
            dto.Items = this._ItemLog.Gets<AuditItemInfo>(result.ItemId);
            return dto;
        }

        public bool IsInProgress ( long appId, string linkType, long linkPk )
        {
            return this._AuditLog.IsInProgress(appId, linkType, linkPk);
        }

        public CreateResult Create ( AuditLogAdd auditLogAdd )
        {
            return this._AuditLog.Create(auditLogAdd);
        }
        public long[] GetRunNodeId ( long logId, long rootBatchNo, int lvl )
        {
            return this._ItemLog.GetRunNodeId(logId, rootBatchNo, lvl);
        }

        public AuditItemState GetLogItem ( long itemId )
        {
            return this._ItemLog.Get<AuditItemState>(itemId);
        }
    }
}
